package com.harmontronics.hanma.paas.paas.domain.app.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.harmontronics.hanma.paas.paas.common.PageBase;
import com.harmontronics.hanma.paas.paas.consts.DbConstants;
import com.harmontronics.hanma.paas.paas.domain.app.entity.HmHttpService;
import com.harmontronics.hanma.paas.paas.domain.app.entity.HttpServiceSetting;
import com.harmontronics.hanma.paas.paas.domain.app.entity.valueobject.AuthTypeEnum;
import com.harmontronics.hanma.paas.paas.domain.app.entity.valueobject.Fields;
import com.harmontronics.hanma.paas.paas.domain.app.entity.valueobject.I18nKeyEnum;
import com.harmontronics.hanma.paas.paas.domain.app.repository.persistence.HmHttpServiceRepository;
import com.harmontronics.hanma.paas.paas.domain.app.repository.persistence.HmModelRepository;
import com.harmontronics.hanma.paas.paas.domain.app.repository.persistence.HttpServiceSettingRepository;
import com.harmontronics.hanma.paas.paas.domain.app.repository.po.HmHttpServicePO;
import com.harmontronics.hanma.paas.paas.domain.app.repository.po.HttpServiceSettingPO;
import com.harmontronics.hanma.paas.paas.exception.ErrorKeyException;
import com.harmontronics.hanma.paas.paas.utils.EscapeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service("hmHttpServiceService")
@DS("#header.App-Unique")
public class HmHttpServiceService {

    @Autowired
    private HmHttpServiceRepository hmHttpServiceRepository;

    @Autowired
    private HttpServiceSettingRepository httpServiceSettingRepository;

    @Autowired
    private HmModelRepository hmModelRepository;


    public HmHttpService findById(Long id) {
        HmHttpServicePO po = hmHttpServiceRepository.getById(id);
        HmHttpService httpService= BeanUtil.toBean(po, HmHttpService.class);
        List<HttpServiceSettingPO> settingPOS = httpServiceSettingRepository.findByServiceId(id);
        httpService.setSettingList(Convert.toList(HttpServiceSetting.class,settingPOS));
        return httpService;
    }

    @Transactional(rollbackFor = Exception.class)
    public void save(HmHttpService hmHttpService) {
        validField(null,Fields.KEY,hmHttpService.getKey());
        hmHttpService.checkMosParam();
        HmHttpServicePO po = BeanUtil.toBean(hmHttpService, HmHttpServicePO.class);
        hmHttpServiceRepository.save(po);
        List<HttpServiceSettingPO> settingPOS = Convert.toList(HttpServiceSettingPO.class,hmHttpService.getSettingList());
        settingPOS.forEach(e->e.setHttpServiceId(po.getId()));
        httpServiceSettingRepository.saveBatch(settingPOS);
    }


    @Transactional(rollbackFor = Exception.class)
    public void update(HmHttpService hmHttpService) {
        hmHttpService.checkMosParam();
        HmHttpServicePO po = hmHttpServiceRepository.getById(hmHttpService.getId());
        po.setRemark(hmHttpService.getRemark());
        po.setName(hmHttpService.getName());
        hmHttpServiceRepository.updateById(po);
        httpServiceSettingRepository.deleteByServiceId(po.getId());
        List<HttpServiceSettingPO> settingPOS = Convert.toList(HttpServiceSettingPO.class,hmHttpService.getSettingList());
        settingPOS.forEach(e->e.setHttpServiceId(po.getId()));
        httpServiceSettingRepository.saveBatch(settingPOS);
    }

    public void remove(List<Long> ids) {
        for(Long id:ids){
            if(hmModelRepository.existByHttpServiceId(id)){
                throw new ErrorKeyException(I18nKeyEnum.HTTP_SERVICE_USING_ERROR);
            }

            httpServiceSettingRepository.deleteByServiceId(id);
            hmHttpServiceRepository.removeById(id);
        }
    }

    public List<HmHttpService> getList() {
        List<HmHttpServicePO> pos = hmHttpServiceRepository.list();
        return Convert.toList(HmHttpService.class, pos);
    }

    public PageBase<HmHttpService> getList(String key, String name, int pageNo, int pageSize) {
        Page<HmHttpServicePO> page = new Page<>(pageNo, pageSize);
        QueryWrapper<HmHttpServicePO> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasLength(key)) {
            queryWrapper.like(Fields.KEY_DB, EscapeUtil.escapeChar(key));
        }
        if (StringUtils.hasLength(name)) {
            queryWrapper.like(Fields.NAME, EscapeUtil.escapeChar(name));
        }
        queryWrapper.orderByDesc(DbConstants.CREATE_DATE);
        IPage<HmHttpServicePO> resultPage =
                hmHttpServiceRepository.selectPage(queryWrapper, page);
        PageBase<HmHttpService> finalPage = PageBase.from(resultPage, HmHttpService.class);
        fillSettingList(finalPage.getData());
        return finalPage;
    }

    private void fillSettingList(List<HmHttpService> dsList) {
        if (dsList.isEmpty()) {
            return;
        }
        List<Long> idList = dsList.stream().map(HmHttpService::getId).collect(Collectors.toList());
        List<HttpServiceSettingPO> settingPOS = httpServiceSettingRepository.findByServiceIdIn(idList);
        for (HmHttpService hs : dsList) {
            List<HttpServiceSettingPO> pos = settingPOS.stream().filter(e -> e.getHttpServiceId().longValue() == hs.getId().longValue()).collect(Collectors.toList());
            hs.setSettingList(Convert.toList(HttpServiceSetting.class, pos));
        }
    }

    public void validField(Long id, String field, String value) {


        if (Fields.KEY.equals(field)) {
            HmHttpServicePO po = hmHttpServiceRepository.findByKey(value);
            if (po == null) {
                return;
            }
            if (id == null) {
                throw new ErrorKeyException(I18nKeyEnum.HTTP_SERVICE_KEY_EXISTS);
            }
            if (po.getId().longValue() != id.longValue()) {
                throw new ErrorKeyException(I18nKeyEnum.HTTP_SERVICE_KEY_EXISTS);
            }
        }
    }

}